#!/bin/bash

# 自动化部署脚本（由系统自动生成，请勿手动修改）
user=`whoami`
# 1. 基础配置（从K8sDeployConfig传入）
cluster_name="{{ .K8sClusterName }}"        # 集群名称
images_version="{{ .ImagesVersion }}"       # 镜像版本
container_runtime="{{ .ContainerRuntime }}" # 容器运行时
network_component="{{ .NetworkComponent }}" # 网络插件
image_repo="{{ .ImageRepo }}"               # 镜像仓库

# 2. Master节点配置（支持1/3主架构）
K8S_MASTER_01="{{.K8sMaster01}}"
{{if .K8sMaster02}}K8S_MASTER_02="{{.K8sMaster02}}"{{end}}
{{if .K8sMaster03}}K8S_MASTER_03="{{.K8sMaster03}}"{{end}}
{{if not .K8sMaster02}}# 单主架构注释冗余节点{{end}}
{{if not .K8sMaster02}}# K8S_MASTER_02=""{{end}}
{{if not .K8sMaster02}}# K8S_MASTER_03=""{{end}}

# 将所有Master节点变量放入数组（按序号01/02/03排序）
masters=(
  "K8S_MASTER_01"
  "K8S_MASTER_02"
  "K8S_MASTER_03"
)

# 循环遍历每个Master节点变量
for master_var in "${masters[@]}"; do
  # 获取变量的实际值（通过间接引用）
  ip=$(eval "echo \${$master_var}")

  # 提取序号（如从"K8S_MASTER_01"中提取"01"）
  index=${master_var##*_}  # 通过通配符截取"_"后的字符串（即序号）

  # 仅处理非空IP的节点
  if [ -n "$ip" ]; then
    echo "配置Master节点 $index（IP: $ip）的主机名..."
    # 执行ssh命令配置主机名（立即生效且永久保存）
    ssh "$ip" "sudo hostnamectl set-hostname master$index && echo master$index | sudo tee /etc/hostname"
    # 检查命令执行结果
    if [ $? -eq 0 ]; then
      echo "Master节点 $index 主机名配置成功"
    else
      echo "警告：Master节点 $index 配置失败"
    fi
  else
    echo "Master节点 $index 未配置IP，跳过..."
  fi
done

mkdir -p /etc/yum.repos.d/bak
mv /etc/yum.repos.d/* /etc/yum.repos.d/bak
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

cat >/etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF


yum clean all
yum install -y wget ansible   keepalived docker-ce docker-ce-cli containerd.io
yum install -y kubelet-{{ .ImagesVersion }} kubeadm-{{ .ImagesVersion }} kubectl-{{ .ImagesVersion }} --disableexcludes=kubernetes
/bin/cp -a /tmp/hosts /etc/ansible/hosts
#wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.14/cri-dockerd-0.3.14-3.el7.x86_64.rpm
wget http://47.97.202.142:1404/cri-dockerd-0.3.14-3.el7.x86_64.rpm
rpm -ivh cri-dockerd-0.3.14-3.el7.x86_64.rpm

# 4. 网络接口列表（仅存储网卡名，与节点顺序对应）
network_name_new="
{{if .clusterMasterNics01}}{{.clusterMasterNics01}}{{end}}
{{if .clusterMasterNics02}}{{.clusterMasterNics02}}{{end}}
{{if .clusterMasterNics03}}{{.clusterMasterNics03}}{{end}}
"

# 5. Keepalived配置模板（明确区分接口和优先级占位符）
keepalived_template="
! Configuration File for keepalived
global_defs {
    router_id {{.K8sClusterName}}
}

vrrp_script chk_k8s {
    script  \"ss -tuln | grep -q ':6443.*LISTEN' && curl -ks --connect-timeout 3 https://127.0.0.1:6443 > /dev/null\"
    interval 3
    weight -50
}

vrrp_instance VI_1 {
    state MASTER
    interface __INTERFACE__  # 此处将被替换为网卡名（如ens33）
    virtual_router_id 151
    priority __PRIORITY__    # 此处将被替换为数字（如90）
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        {{.K8sVip}}
    }
    track_script {
        chk_k8s
    }
}
"

# 6. 提取有效网卡列表（过滤空行，确保数组元素为网卡名）
mapfile -t nic_list < <(echo "$network_name_new" | grep -v '^$')

# 7. 定义节点IP与对应优先级（严格一一对应）
master_ips=("$K8S_MASTER_01" "$K8S_MASTER_02" "$K8S_MASTER_03")
node_priorities=(90 80 70)  # 固定优先级：第1节点90，第2节点80，第3节点70

# 8. 循环生成配置文件（确保优先级用数字，接口用网卡名）
for index in "${!master_ips[@]}"; do
    current_ip="${master_ips[$index]}"
    # 跳过空IP节点（单主架构时后两个IP为空）
    if [ -z "$current_ip" ]; then
        continue
    fi

    # 获取当前节点的网卡名（优先用对应索引的网卡，无则默认eth0）
    if [ $index -lt ${#nic_list[@]} ] && [ -n "${nic_list[$index]}" ]; then
        current_nic="${nic_list[$index]}"
    else
        current_nic="eth0"
        echo "警告：节点$current_ip未找到对应网卡，使用默认网卡$current_nic"
    fi

    # 获取当前节点的优先级（严格使用数字，索引越界时默认90）
    if [ $index -lt ${#node_priorities[@]} ]; then
        current_priority="${node_priorities[$index]}"
    else
        current_priority=90
        echo "警告：节点$current_ip未找到对应优先级，使用默认值$current_priority"
    fi

    # 生成配置文件：替换__INTERFACE__为网卡名，__PRIORITY__为数字
    config_filename="${current_ip}_keepalived.conf"
    echo "$keepalived_template" | sed \
        -e "s/__INTERFACE__/$current_nic/" \
        -e "s/__PRIORITY__/$current_priority/" \
        > "$config_filename"

    # 验证配置文件有效性
    if [ -s "$config_filename" ] && grep -q "$current_priority" "$config_filename"; then
        echo "成功生成配置：$config_filename（网卡：$current_nic，优先级：$current_priority）"
    else
        echo "错误：节点$current_ip的配置文件无效（优先级未正确设置）"
        rm -f "$config_filename"
    fi
done

echo "添加ansible节点信息完成"
cat /etc/ansible/hosts | grep -v ^$


# 9. 分发配置文件到各节点
node_index=1
while true; do
    # 构造节点变量名（K8S_MASTER_01、K8S_MASTER_02等）
    node_var="K8S_MASTER_$(printf "%02d" $node_index)"
    node_ip=$(eval "echo \${$node_var}")

    # 无更多节点时退出循环
    if [ -z "$node_ip" ]; then
        break
    fi

    # 检查配置文件是否存在且优先级正确
    target_file="${node_ip}_keepalived.conf"
    if [ ! -f "$target_file" ] || [ ! -s "$target_file" ]; then
        echo "跳过分发：$node_var（$node_ip）的配置文件不存在或为空"
        node_index=$((node_index + 1))
        continue
    fi

    # 分发配置文件
    echo "分发配置到$node_var（$node_ip）..."
    if scp "$target_file" "${node_ip}:/etc/keepalived/keepalived.conf"; then
        echo "成功分发到$node_ip"
    else
        echo "失败：分发到$node_ip时出错"
    fi

    node_index=$((node_index + 1))
done

echo "所有节点的Keepalived配置处理完成"

# 定义节点变量（假设这些变量由Gin模板替换后传入，空值为'<no value>'）
# 临时文件存储要写入的内容
temp_hosts=$(mktemp)

# 循环处理3个节点，过滤空值
for i in {1..3}; do
    # 拼接变量名（如K8sMaster01、K8sMaster02）
    var="K8S_MASTER_0${i}"
    # 获取变量值（间接引用）
    ip=$(eval "echo \${$var}")
    # 主机名（master01、master02）
    hostname="master0${i}"

    # 仅当值不是'<no value>'时写入
    if [ "$ip" != "" ]; then
        echo "${ip} ${hostname}" >> "$temp_hosts"
    fi
done

# 将生成的内容追加到/etc/hosts（如需覆盖请用>，建议先备份）
cat "$temp_hosts" > /etc/hosts

# 清理临时文件
rm -f "$temp_hosts"

echo "hosts配置完成"

echo "
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
#localAPIEndpoint:
nodeRegistration:
  #containerd
  #criSocket: unix:///var/run/containerd/containerd.sock
  #cri-dockerd
  criSocket: unix:///var/run/cri-dockerd.sock
  imagePullPolicy: IfNotPresent
#  name: node
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
#imageRepository: registry.k8s.io
imageRepository: {{ .ImageRepo }}
kind: ClusterConfiguration
kubernetesVersion: {{ .ImagesVersion }}
controlPlaneEndpoint: {{.K8sVip}}:6443
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.224.0.0/16
scheduler: {}
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
" > /home/$user/kubeadm-init.yaml

echo "
- hosts: k8s_master
  remote_user: root
  tasks:
  - name: linux env
    shell: systemctl stop firewalld && systemctl disable firewalld && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux && setenforce 0 && echo "net.bridge.bridge-nf-call-iptables = 1" > /etc/sysctl.conf && modprobe br_netfilter &&  sysctl -p /etc/sysctl.conf && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
    ignore_errors: yes
  - name: crontab update
    shell: cat /var/spool/cron/root | grep ntpdate ||  echo "* */1 * * * /usr/sbin/ntpdate ntp.aliyun.com" > /var/spool/cron/root
  - name: k8s env
    shell: swapoff -a && sysctl -w vm.swappiness=0 && sed -i '/swap/d' /etc/fstab && mkdir -p /etc/systemd/system/kubelet.service.d/
    ignore_errors: yes
  - name: 启动keepalived docker cri-docker初始化配置
    shell: systemctl restart keepalived && systemctl  restart docker && systemctl restart  cri-docker
  - name:  k8s在线镜像下载
    shell: kubeadm config images pull --kubernetes-version=v{{ .ImagesVersion }} --image-repository registry.aliyuncs.com/google_containers --cri-socket unix:///var/run/cri-dockerd.sock
  - name: iptables env
    shell: echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
  - name: docker启动替换配置cri-docker
    shell: sed -i 's|ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd://|ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9|g' /usr/lib/systemd/system/cri-docker.service
  - name: enable 组件
    shell: systemctl enable docker.service && systemctl enable kubelet.service  && systemctl enable keepalived && systemctl enable  cri-docker && systemctl restart docker
  - name: restart 组件
    shell:  systemctl daemon-reload && systemctl restart docker && systemctl restart kubelet.service  && systemctl restart  cri-docker
  - name: 部署master节点
    shell: kubeadm init --config=/home/{{.InstallUser}}/kubeadm-init.yaml
  - name: k8s env
    shell: mkdir -p /{{.InstallUser}}/.kube/ && cp /etc/kubernetes/admin.conf /{{.InstallUser}}/.kube/config
##########高级选项组件安装###############
  - name: k8s 端口范围开放1000-65535
    ansible.builtin.shell: |
      cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep service-node-port-range || sed -i '/    - --secure-port=6443/i\    - --service-node-port-range=1000-65535' /etc/kubernetes/manifests/kube-apiserver.yaml
  - name: 下载 Helm 组件（v3.19.0 Linux amd64）
    ansible.builtin.get_url:
      #url: https://get.helm.sh/helm-v3.19.0-linux-amd64.tar.gz
      url: http://47.97.202.142:1404/helm-v3.19.0-linux-amd64.tar.gz
      dest: /home/{{.InstallUser}}/helm-v3.19.0-linux-amd64.tar.gz  # 保存路径（建议指定具体目录）
      mode: '0644'  # 文件权限
      checksum: sha256:https://get.helm.sh/helm-v3.19.0-linux-amd64.tar.gz.sha256sum  # 校验文件完整性
      timeout: 60  # 超时时间（秒）
    register: helm_download  # 可选：注册结果，后续可判断是否下载成功
  - name: 解压helm
    shell: tar -xf /home/{{.InstallUser}}/helm-v3.19.0-linux-amd64.tar.gz
    ignore_errors: yes
  - name: copy helm
    copy: src=/root/linux-amd64/helm  dest=/usr/bin/ mode=755
    ignore_errors: yes
  - name: 导入cilium源
    shell: helm repo add cilium https://helm.cilium.io/
    ignore_errors: yes
  - name: install cilium组件
    shell: sleep 5 && helm install cilium cilium/cilium --version 1.15.4   --namespace kube-system --set kubeProxyReplacement=strict  --set k8sServiceHost={{.K8sVip}} --set k8sServicePort=6443 --set hubble.relay.enabled=true   --set hubble.ui.enabled=true
    ignore_errors: yes
    " > /home/$user/ansible_master.yaml
    ansible-playbook /home/$user/ansible_master.yaml

    #生成多集群master以及node接入token私钥
#    mkdir -p /root/.kube/
#    cp /etc/kubernetes/admin.conf /root/.kube/config
    token=`kubeadm token list | tail -n 1 | awk '{print $1}'`
    ssl=`openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'`
    vip=`cat /etc/keepalived/keepalived.conf | grep -Po "\d+\.\d+\.\d+\.\d+"`
    echo "kubeadm join --token $token --discovery-token-ca-cert-hash sha256:$ssl  {{.K8sVip}}:6443 --control-plane --cri-socket unix:///var/run/cri-dockerd.sock " > /home/$user/token_master
    echo "kubeadm join --token $token --discovery-token-ca-cert-hash sha256:$ssl  {{.K8sVip}}:6443 --cri-socket unix:///var/run/cri-dockerd.sock  " > /home/$user/token_node

